/**
 *\file maison.c
 *\author Raphaël Diana
 *\author Imad Smaani
 */
#include "maison.h"

/* ---------------------------------------------- GESTION STRUCTURE & MEMOIRE ----------------------------------------------*/
Maison* initMaison ()
{
    Maison* maison;
    maison=(Maison*)malloc(sizeof(Maison));
    assert(maison!=NULL);
    maison->handMaison=NULL;
    maison->sabot=initSabot();
    return maison;
}

void distribuerCarte(Maison * maison, Joueur * joueur)
{
    int i, j;
    assert(maison!=NULL && joueur!=NULL);
    for (i=0; i<2; i++)
    {
        piocherCarte(maison->handMaison, maison); /* On tire les 2 cartes du croupier */
        valeurMain(maison->handMaison);
        for(j=0; j<3; j++)
        {
            if(testMiseCase(joueur, 4*j)!=0)
            {
                piocherCarte(joueur->jeu[4*j].hand, maison); /* On tire les 2 cartes du joueur */
                valeurMain(joueur->jeu[4*j].hand);
            }
        }
    }
}

void detruireMaison (Maison ** maison)
{
    assert(*maison!=NULL);
    testamentListe(&(*maison)->handMaison);
    detruitSabot(&(*maison)->sabot);
    free(*maison);
    *maison=NULL;
}
/* ---------------------------------------------- FIN GESTION STRUCTURE & MEMOIRE ----------------------------------------------*/

Liste* getListeMaison(const Maison* maison)
{
    return maison->handMaison;
}

int gagneListe(const Joueur* joueur, const Maison* maison, int indice)
{
    assert(getListeJoueur(joueur, indice)!=NULL && getListeMaison(maison)!=NULL);
    if(getValeurMain(getListeJoueur(joueur, indice))!=getValeurMain(getListeMaison(maison)))/*cas gagne ou perd*/
    {
        return ( (testBlackjackCase(joueur, indice) && !testBlackjack(getListeMaison(maison)))
                 || (valeurMain(getListeJoueur(joueur, indice))>valeurMain(getListeMaison(maison)) && !testSaute(getListeJoueur(joueur, indice)))
                 || (testSaute(getListeMaison(maison)) && !testSaute(getListeJoueur(joueur, indice))) );
    }
    else
    {
        if((testBlackjackCase(joueur, indice)+testBlackjack(getListeMaison(maison)))==1)/*si il y a un unique Blackjack*/
        {
            return testBlackjackCase(joueur, indice);
        }
        else
        {
            return -1;
        }
    }
}

/* ---------------------------------------------- AFFICHAGE ----------------------------------------------*/
void afficheHandMaison(const Maison * m,unsigned int carte)
{
    if(carte==1)
    {
        printf("\n----- Main du croupier ----- \n");
        afficherCarte(getInfo(m->handMaison, 1));
    }
    else if(carte==2)
    {
        printf("\n----- Main du croupier ----- \n");
        afficheMain(m->handMaison);
    }
}
/* ---------------------------------------------- FIN AFFICHAGE ----------------------------------------------*/

void piocherCarte (Liste * h, Maison * m)
{
    Carte * c;
    c=tirerCarte(m->sabot->talon);
    insertElement(h,c);
}

void payerJoueur(Maison* maison, Joueur* joueur, int indice)
{
    if(testMiseCase(joueur, indice)>0)
    {
        if(gagneListe(joueur, maison, indice)==1)/*cas le joueur gagne*/
        {
            if(testBlackjack(joueur->jeu[indice].hand))
            {
                paiementJoueur(joueur, (unsigned int)((1+(3/2.0))*joueur->jeu[indice].mise));/*cas du Blackjack, paiement a 3 pour 2*/
            }
            else
            {
                paiementJoueur(joueur, (unsigned int)(1+1)*joueur->jeu[indice].mise);/*cas gagne simplement paiement a 1 pour 1*/
            }
        }
        else
        {
            if(testBlackjack(maison->handMaison)==1)
            {
                paiementJoueur(joueur, (unsigned int)2*joueur->jeu[indice].assurance);/*paiement assurance 2 pour 1*/
            }
            else
            {
                if(gagneListe(joueur, maison, indice)==-1)
                {
                    paiementJoueur(joueur, joueur->jeu[indice].mise);/*remboursement*/
                }
            }
        }
    }
}

void proposerAssurance(Maison * m,Joueur *j, int i)
{
    char r;

    if(getValeurCarte(getInfo(m->handMaison, 1)) == 11 && testMiseCase(j, i)) /* Le croupier a un As decouvert, on propose l'assurance */
    {
        do
        {
            printf("\nVoulez-vous prendre l'assurance pour votre case %i? (O/N)\n", i/4+1);
            r = getchar() | 0x20;
            while(getchar()!='\n');
        }
        while(r!='o' && r!='n');
        if(r=='o')
        {
            printf("\nVous avez choisi de prendre l'assurance\n");
        }
        prendreAssurance(j,&j->jeu[i], r=='o');
    }

}

void ramasserCarte (Joueur * joueur, Maison * maison)
{
    testamentJeuJoueur(joueur);
    testamentListe(&maison->handMaison);
}

void tirageMaison (Maison * maison, unsigned int limite)
{
    assert(maison!=NULL);
    if(testBlackjack(maison->handMaison))
    {
        printf("Blackjack de la banque! \n");
    }
    while(getValeurMain(maison->handMaison)< limite) /* Tant que la limite n'est pas atteinte on tire */
    {
        piocherCarte(maison->handMaison, maison);
    }
}
void separationListe(Joueur* joueur, Maison* maison, int indice)
{
    int i;
    if(getIndiceCase(joueur, indice)<=3)
    {
        i=2;
    }
    else
    {
        i=1;
    }
    separerListeJoueur(joueur, indice);
    piocherCarte(joueur->jeu[indice].hand, maison);
    piocherCarte(joueur->jeu[indice+i].hand, maison);
}


void initMainMaison(Maison * maison)
{
    assert(maison->handMaison==NULL);
    maison->handMaison=initListe();
}
